﻿package net.wangit.framework.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.wangit.Path;
import net.wangit.framework.exception.ConfigurationException;
import net.wangit.support.ActionInterceptor;
import net.wangit.support.PageInterceptor;
import net.wangit.support.UnitInterceptor;
import net.wangit.util.Checker;
import net.wangit.util.ClassUtil;
import net.wangit.util.FileUtil;
import net.wangit.util.StringUtil;
import net.wangit.util.XMLUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;


public class InterceptorLoader {

	private static final Log log = LogFactory
			.getLog(net.wangit.framework.util.InterceptorLoader.class);
	private static final String FILE = "interceptors.xml";
	private static final String ACTION = "action";
	private static final String PAGE = "page";
	private static final String UNIT = "unit";
	private static final String INTERCEPTOR = "interceptor";
	private static Map<String, Map> interceptors = new HashMap<String, Map>();
	private static Map defaultInterceptors;

	public InterceptorLoader() {
	}

	/**
	 * 加载默认拦截器:配置在${home}/domain/interceptors.xml文件中
	 */
	public static void loadDefaultInterceptors() {
		defaultInterceptors = load((new StringBuilder(String.valueOf(Path
				.getDomainRootPath()))).append(InterceptorLoader.FILE)
				.toString());
	}

	/**
	 * 加载域拦截器:配置在${home}/domain/域/interceptors.xml文件中
	 */
	public static void loadDomainInterceptors(String domain) {
		interceptors.put(domain, load((new StringBuilder(String.valueOf(Path
				.getDomainPath(domain)))).append(InterceptorLoader.FILE)
				.toString()));
	}

	// 获取Action拦截器
	public static Iterator getActionInterceptors(String domain,
			List interceptorList) {
		return getIterator(getInterceptors(domain, InterceptorLoader.ACTION),
				interceptorList);
	}

	// 获取Page拦截器
	public static Iterator getPageInterceptors(String domain,
			List interceptorList) {
		return getIterator(getInterceptors(domain, InterceptorLoader.PAGE),
				interceptorList);
	}

	// 获取Unit拦截器
	public static Iterator getUnitInterceptors(String domain,
			List interceptorList) {
		return getIterator(getInterceptors(domain, InterceptorLoader.UNIT),
				interceptorList);
	}

	private static Iterator getIterator(List list1, List list2) {
		if (list1 == null && list2 == null)
			return null;
		if (list1 == null)
			return list2.iterator();
		if (list2 == null) {
			return list1.iterator();
		} else {
			List temp = new ArrayList();
			temp.addAll(list1);
			temp.addAll(list2);
			return temp.iterator();
		}
	}

	/**
	 * 加载Action拦截器
	 * 
	 * @param interceptorsStr
	 *            以","分割的拦截器类名
	 * @return
	 * @throws Exception
	 */
	public static List<ActionInterceptor> loadActionInterceptors(
			String interceptorsStr) throws Exception {
		List<ActionInterceptor> interceptors = new ArrayList<ActionInterceptor>();
		if (!Checker.isEmpty(interceptorsStr)) {
			String[] is = StringUtil.split(interceptorsStr, ",");
			for (int i = 0; i < is.length; i++)
				if (!Checker.isEmpty(is[i]))
					interceptors.add(loadActionInterceptor(is[i].trim()));

		}
		return interceptors;
	}

	/**
	 * 加载Pag拦截器
	 * 
	 * @param interceptorsStr
	 *            以","分割的拦截器类名
	 * @return
	 * @throws Exception
	 */
	public static List<PageInterceptor> loadPageInterceptors(
			String interceptorsStr) throws Exception {
		List<PageInterceptor> interceptors = new ArrayList<PageInterceptor>();
		if (!Checker.isEmpty(interceptorsStr)) {
			String[] is = StringUtil.split(interceptorsStr, ",");
			for (int i = 0; i < is.length; i++)
				if (!Checker.isEmpty(is[i]))
					interceptors.add(loadPageInterceptor(is[i].trim()));

		}
		return interceptors;
	}

	/**
	 * 加载Unit拦截器
	 * 
	 * @param interceptorsStr
	 *            以","分割的拦截器类名
	 * @return
	 * @throws Exception
	 */
	public static List<UnitInterceptor> loadUnitInterceptors(
			String interceptorsStr) throws Exception {
		List<UnitInterceptor> interceptors = new ArrayList<UnitInterceptor>();
		if (!Checker.isEmpty(interceptorsStr)) {
			String[] is = StringUtil.split(interceptorsStr, ",");
			for (int i = 0; i < is.length; i++)
				if (!Checker.isEmpty(is[i]))
					interceptors.add(loadUnitInterceptor(is[i].trim()));

		}
		return interceptors;
	}

	private static Map load(String path) {
		Map map = new HashMap();
		if (!FileUtil.exists(path))
			return null;
		try {
			Document document = XMLUtil.parseByPath(path);
			Element root = document.getRootElement();
			List interceptors = new ArrayList();
			List list = root.element(InterceptorLoader.ACTION).elements(
					InterceptorLoader.INTERCEPTOR);
			if (Checker.isEmpty(list)) {
				map.put(InterceptorLoader.ACTION, null);
			} else {
				for (int i = 0; i < list.size(); i++) {
					Element element = (Element) list.get(i);
					interceptors.add(loadActionInterceptor(element.getText()
							.trim()));
				}

				map.put(InterceptorLoader.ACTION, interceptors);
			}
			interceptors = new ArrayList();
			list = root.element(InterceptorLoader.PAGE).elements(
					InterceptorLoader.INTERCEPTOR);
			for (int i = 0; i < list.size(); i++) {
				Element element = (Element) list.get(i);
				interceptors.add(loadPageInterceptor(element.getText().trim()));
			}

			map.put(InterceptorLoader.PAGE, interceptors);
			interceptors = new ArrayList();
			list = root.element(InterceptorLoader.UNIT).elements(
					InterceptorLoader.INTERCEPTOR);
			for (int i = 0; i < list.size(); i++) {
				Element element = (Element) list.get(i);
				interceptors.add(loadUnitInterceptor(element.getText().trim()));
			}

			map.put(InterceptorLoader.UNIT, interceptors);
		} catch (Exception e) {
			log.error((new StringBuilder("could not load interceptors: "))
					.append(path).toString(), e);
			throw new ConfigurationException((new StringBuilder(
					"could not load interceptors: ")).append(path).toString(),
					e);
		}
		return map;
	}

	private static List getInterceptors(String domain, String key) {
		Map interceptorsMap = (Map) interceptors.get(domain);
		if (interceptorsMap != null)
			return (List) interceptorsMap.get(key);
		else
			return (List) defaultInterceptors.get(key);
	}

	private static ActionInterceptor loadActionInterceptor(String interceptor)
			throws Exception {
		try {
			ActionInterceptor i = (ActionInterceptor) ClassUtil.loadClass(
					interceptor).newInstance();
			return i;
		} catch (Exception e) {
			throw e;
		}
	}

	private static PageInterceptor loadPageInterceptor(String interceptor)
			throws Exception {
		try {
			PageInterceptor i = (PageInterceptor) ClassUtil.loadClass(
					interceptor).newInstance();
			return i;
		} catch (Exception e) {
			throw e;
		}
	}

	private static UnitInterceptor loadUnitInterceptor(String interceptor)
			throws Exception {
		try {
			UnitInterceptor i = (UnitInterceptor) ClassUtil.loadClass(
					interceptor).newInstance();
			return i;
		} catch (Exception e) {
			log.error((new StringBuilder(
					"could not load the unit interceptor: ")).append(
					interceptor).toString());
			throw e;
		}
	}

}
